Part 36: Visual Cortex
Part 36 - Visual Cortex=== Trash World Inbox ===
Last time, I destroyed Snaxnet's nuclear centrifuges, with high scores of 198, 44 and 7.
Let's see what improvements the thread came up with.
GuavaMoment posted:
After receiving a signal over M, create 5 exas, one for each centrifuge. Test to see if your centrifuge has the highest pressure, otherwise die. Yes, there's only room for 4 exas, but one will die soon enough for the 5th to enter the testing room. Then go turn off your centrifuge and send a done signal. 136/97/22.Snaxnet has been a play on words with stuxnet the entire time, a real life virus made to shut down nuclear centrifuges. I'm sure Zach felt really clever designing this ridiculous challenge for a joke.code:
LINK 800 LINK 799 MARK REPLS VOID M REPL 1 REPL 2 REPL 3 REPL 4 COPY #ZGC0 X TEST X = 0 TJMP DIE TEST #ZGC1 > X TJMP DIE TEST #ZGC2 > X TJMP DIE TEST #ZGC3 > X TJMP DIE TEST #ZGC4 > X TJMP DIE REPL REPLS LINK -1 LINK 798 JUMP DIE MARK 1 COPY #ZGC1 X TEST X = 0 TJMP DIE TEST #ZGC0 > X TJMP DIE TEST #ZGC2 > X TJMP DIE TEST #ZGC3 > X TJMP DIE TEST #ZGC4 > X TJMP DIE REPL REPLS LINK -1 LINK 798 JUMP POWEROFF1 MARK 2 COPY #ZGC2 X TEST X = 0 TJMP DIE TEST #ZGC1 > X TJMP DIE TEST #ZGC0 > X TJMP DIE TEST #ZGC3 > X TJMP DIE TEST #ZGC4 > X TJMP DIE REPL REPLS LINK -1 LINK 798 JUMP POWEROFF2 MARK 3 COPY #ZGC3 X TEST X = 0 TJMP DIE TEST #ZGC1 > X TJMP DIE TEST #ZGC2 > X TJMP DIE TEST #ZGC0 > X TJMP DIE TEST #ZGC4 > X TJMP DIE REPL REPLS LINK -1 LINK 798 JUMP POWEROFF3 MARK 4 COPY #ZGC4 X TEST X = 0 TJMP DIE TEST #ZGC1 > X TJMP DIE TEST #ZGC2 > X TJMP DIE TEST #ZGC3 > X TJMP DIE TEST #ZGC0 > X TJMP DIE REPL REPLS LINK -1 LINK 798 LINK 800 MARK POWEROFF3 LINK 800 MARK POWEROFF2 LINK 800 MARK POWEROFF1 LINK 800 MARK DIE COPY 0 #POWR COPY 999 M ;XB COPY 999 M
silentsnack then had several more speed improvements, starting with this one.
silentsnack posted:
95/63/27code:
;XA LINK 800 LINK 799 MARK 0 TEST #ZGC1 < #ZGC0 FJMP 1 TEST #ZGC2 < #ZGC0 FJMP 2 TEST #ZGC3 < #ZGC0 FJMP 3 TEST #ZGC4 > #ZGC0 MULI T 4 T ADDI 7 T M ADDI T 1 T JUMP WAIT MARK 1 TEST #ZGC2 < #ZGC1 FJMP 2 TEST #ZGC3 < #ZGC1 FJMP 3 TEST #ZGC4 > #ZGC1 MULI T 3 T ADDI 8 T M ADDI T 1 T JUMP WAIT MARK 2 TEST #ZGC3 < #ZGC2 FJMP 3 TEST #ZGC4 > #ZGC2 MULI T 2 T ADDI T 9 M ADDI T 2 T JUMP WAIT MARK 3 TEST #ZGC4 > #ZGC3 ADDI T 10 M ADDI T 3 T MARK WAIT SUBI T 1 T TJMP WAIT JUMP 0 ;XB COPY 5 X LINK 800 LINK 798 MARK LOOP MODI -1 X X COPY M T REPL LOOP MODI T 7 #POWR LINK 800 MODI T 8 #POWR LINK 800 MODI T 9 #POWR LINK 800 MODI T 10 #POWR LINK 800 MODI T 11 #POWR ;XC COPY 40 T MARK WAIT SUBI T 1 T TJMP WAIT LINK 800 LINK 799 KILL
silentsnack posted:
75/87/32code:
;XA LINK 800 LINK 799 COPY 3 X MARK 0 TEST #ZGC1 < #ZGC0 FJMP 1 TEST #ZGC2 < #ZGC0 FJMP 2 TEST #ZGC3 < #ZGC0 FJMP 3 TEST #ZGC4 > #ZGC0 MULI T 4 T REPL NEXT LINK -1 LINK 798 COPY T #POWR LINK 800 LINK 800 LINK 800 LINK 800 SUBI 4 T #POWR HALT MARK 1 TEST #ZGC2 < #ZGC1 FJMP 2 TEST #ZGC3 < #ZGC1 FJMP 3 TEST #ZGC4 > #ZGC1 MULI T 3 T REPL NEXT LINK -1 LINK 798 LINK 800 COPY T #POWR LINK 800 LINK 800 LINK 800 SUBI 3 T #POWR HALT MARK 2 TEST #ZGC3 < #ZGC2 FJMP 3 TEST #ZGC4 > #ZGC2 MULI T 2 T REPL NEXT LINK -1 LINK 798 LINK 800 LINK 800 COPY T #POWR LINK 800 LINK 800 SUBI 2 T #POWR HALT MARK 3 TEST #ZGC4 > #ZGC3 ADDI T 2 T REPL NEXT LINK -1 LINK 798 LINK 800 LINK 800 LINK 800 MODI 2 T #POWR LINK 800 MODI 3 T #POWR HALT MARK NEXT MODI -1 X X ADDI T 1 T MARK WAIT SUBI T 1 T TJMP WAIT JUMP 0 ;XB COPY 22 T LINK 800 LINK 798 REPL WAIT MARK UGH LINK 800 SUBI T 1 T REPL UGH MARK WAIT NOOP SUBI T 1 T TJMP WAIT COPY 0 #POWR
silentsnack posted:
62/100/40code:
;XA LINK 800 LINK 799 ;BEHOLD! SPAGHETTI! MARK 0 TEST #ZGC1 < #ZGC0 FJMP 1 TEST #ZGC2 < #ZGC0 FJMP 2 TEST #ZGC3 < #ZGC0 FJMP 3 TEST #ZGC4 > #ZGC0 REPL KILL_0 FJMP WAIT1 JUMP WAIT5 MARK 1 TEST #ZGC2 < #ZGC1 FJMP 2 TEST #ZGC3 < #ZGC1 FJMP 3 TEST #ZGC4 > #ZGC1 REPL KILL_1 FJMP WAIT2 JUMP WAIT5 MARK 2 TEST #ZGC3 < #ZGC2 FJMP 3 TEST #ZGC4 > #ZGC2 REPL KILL_2 FJMP WAIT3 JUMP WAIT4 MARK 3 TEST #ZGC4 > #ZGC3 REPL KILL_3 FJMP WAIT4 NOOP ;LOOKING SILLY ENOUGH? MARK WAIT5 NOOP MARK WAIT4 NOOP MARK WAIT3 NOOP MARK WAIT2 NOOP MARK WAIT1 NOOP JUMP 0 ;WHY MARK KILL_0 LINK -1 LINK 798 COPY T #POWR LINK 800 LINK 800 LINK 800 LINK 800 DIVI 0 T #POWR MARK KILL_1 LINK -1 LINK 798 LINK 800 COPY T #POWR LINK 800 LINK 800 LINK 800 DIVI 0 T #POWR MARK KILL_2 LINK -1 LINK 798 LINK 800 LINK 800 COPY T #POWR LINK 800 LINK 800 DIVI 0 T #POWR MARK KILL_3 LINK -1 LINK 798 LINK 800 LINK 800 LINK 800 COPY T #POWR LINK 800 DIVI 0 T #POWR ;XB LINK 800 COPY 16 T REPL CASCADE ;SWITCHBOARD CLEANUP LINK 799 JUMP WAIT ;WIPE UR CENTRIFUGES MARK CASCADE LINK 798 NOOP REPL WAIT MARK UGH LINK 800 SUBI T 1 T REPL UGH MARK WAIT NOOP SUBI T 1 T TJMP WAIT KILL COPY 0 #POWR
silentsnack also improved the low lines solution.
silentsnack posted:
It's possible to save a lot of code if you reuse lines, and still end up running quickly. This time around I haven't optimized all that much getting the solutions working to implement whichever ideas I was going for.
Like the fact that the hardware registers are so annoying here's a solution that only includes one instance of ["#ZGC"]
374/33/49code:
LINK 800 MARK MAIN_LOOP LINK 799 MAKE @REP 5 COPY #ZGC@{0,1} F @END LINK -1 LINK 798 MARK MAX SEEK -1 COPY F X SEEK -5 MARK PARSE TEST F > X TJMP MAX TEST EOF FJMP PARSE SEEK -5 MARK FORWARD TEST F = X TJMP STOP LINK 800 JUMP FORWARD MARK STOP WIPE DIVI 0 X #POWR MARK REVERSE LINK -1 REPL REVERSE JUMP MAIN_LOOP
=== Mitsuzen HDI-10 - Visual Cortex ===
So, the part about the world not being real...
I think maybe they were onto something.
Two votes this time, one for "That's ridiculous" and one for "Not you, too". I'll roll a die to break the tie.
Not you, too...
They didn't have the right idea about how to deal with it, of course, but...
There's something I've been suspicious about for a while now.
I'm going to have to do some more tests.
My eye is acting up. Must be the phage spreading...
More phage problems, huh?
There's a rumor that the phage originally came from a research lab...
A human-machine interface experiment that found its way into the wild.
Two votes for the same option.
Can we talk about this after I fix my eye?
It's just funny...
I remember some of that research.
It was happening right next door to us.
"Us?" Where do you come from?
OST: EXA Power
The assignment:
- Read a value from each of the optic nerves present and write the correct value to the nerve that runs deeper into your visual cortex (V-CTX). To determine the value that should be written, count the number of values read that are greater than -55, multiply that count by 5 and then subtract 75. Repeat ad infinitum.
- It is not necessary to leave no trace. Your EXAs should be written to operate indefinitely.
- For more information see "Debugging the Phage" in the first issue of the zine.
Alright, to do this I'll certainly need an EXA in each host that has a nerve. Let's first get them out there.
code:
LINK 800
REPL GORIGHT
LINK 1
REPL WRITER
REPL GORIGHT
LINK 1
MARK GORIGHT
REPL READER
LINK -3
JUMP GORIGHT
MARK READER
VOID M
MARK WRITER
LINK 3
VOID M
The VOID Ms which I used to pause the EXAs now need to be replaced by real code. A naive approach might look like this.
code:
LINK 800
REPL GORIGHT
LINK 1
REPL WRITER
REPL GORIGHT
LINK 1
MARK GORIGHT
REPL READER
LINK -3
JUMP GORIGHT
MARK READER
TEST #NERV > -55
COPY T M
JUMP READER
MARK WRITER
LINK 3
MARK WRITE
COPY 0 X
@REP 9
ADDI M X X
@END
MULI X 5 X
SUBI X 75 #NERV
JUMP WRITE
There's a lot of ways to solve this. Let's start with a way that keeps the code at minimal Activity, even if it's slow.
code:
LINK 800
REPL GORIGHT
LINK 1
REPL WRITER
REPL GORIGHT
LINK 1
MARK GORIGHT
REPL READER
LINK -3
JUMP GORIGHT
MARK READER
TEST #NERV > -55
COPY T M
COPY 5 T
MARK WAIT
SUBI T 1 T
TJMP WAIT
JUMP READER
MARK WRITER
LINK 3
MARK WRITE
COPY 0 X
@REP 9
ADDI M X X
@END
MULI X 5 X
SUBI X 75 #NERV
JUMP WRITE
Today we're battling top percentiles of 334, 27 and 10.
To get the size down to 29, I can roll up that ADDI loop, using T as a counter. Also, that multiply-by-five step can be done when sending T to M.
code:
LINK 800
REPL GORIGHT
LINK 1
REPL WRITER
REPL GORIGHT
LINK 1
MARK GORIGHT
REPL READER
LINK -3
JUMP GORIGHT
MARK READER
TEST #NERV > -55
MULI 5 T M
COPY 13 T
MARK WAIT
SUBI T 1 T
TJMP WAIT
JUMP READER
MARK WRITER
LINK 3
MARK WRITE
COPY 0 X
COPY 9 T
MARK LOOP
ADDI M X X
SUBI T 1 T
TJMP LOOP
SUBI X 75 #NERV
JUMP WRITE
To make a faster solution, I first tried to see if I can have a row of EXAs traverse the grid like lemmings, each one reading every value in turn, so that you can basically write to the visual cortex every cycle. That's not possible - the incoming #NERV registers don't get a new value until after a write to the visual cortex, not after a read like in many other assignments. That fact makes the puzzle much harder.
That means that if I want to use parallelism with the bottleneck being that single write, I need to get the data from all those nerves to the writer EXA as fast as possible. The best way to do that seems to optimize M.
As we've seen in earlier updates, one way to do so is to send two data points with one M call. Since an M call takes two cycles, if you can do this without wasting another cycle somewhere it will always be faster than sending a single data point with one M call.
So I need to make one EXA responsible for at least two nerves. I tried a whole bunch of different designs. For example, you could have 3 reader EXAs, each responsible for an entire row of 3 nerves. That solution wasn't any faster than what I already had.
Another design would be to have each EXA responsible for 2 nerves. Of course, with 9 nerves that won't quite work out.
I guess you could have 4 EXAs, each responsible for two nerves, and then a 5th one responsible for both reading the last nerve and writing. However, if you try you will run into a topological issue. It's not possible to divide the tiles of this grid, including the visual cortex nerve, into adjacent pairs. So one EXA would have to walk further for no reason. It's possible the result is still faster than what I have now but I didn't try.
Instead I decided to divide the responsibilities as such:
Even though an EXA responsible for 3 nerves seems slower, I figured I could get away with using one of these because it isn't possible for all of them to send on M at once anyway.
code:
LINK 800
REPL RIGHT
REPL SYNC
LINK 1
REPL LRLOOP
REPL WRITER
LINK 1
JUMP LRLOOP
MARK WRITER
LINK 3
MARK WRITE
COPY -75 X
ADDI M X X
ADDI M X X
ADDI M X X
ADDI M X #NERV
JUMP WRITE
MARK SYNC
NOOP
NOOP
NOOP
MARK LRLOOP
TEST #NERV > -55
COPY T X
LINK -3
TEST #NERV > -55
ADDI X T X
MULI X 5 M
LINK 3
NOOP
NOOP
NOOP
NOOP
JUMP LRLOOP
MARK RIGHT
LINK -3
LINK -3
MARK OLOOP
TEST #NERV > -55
COPY T X
LINK 1
TEST #NERV > -55
ADDI X T X
LINK 1
TEST #NERV > -55
ADDI X T X
MULI X 5 M
LINK -1
LINK -1
JUMP OLOOP
And it works. The LRLOOP handles the EXAs that have two nerves, the OLOOP is for the three nerves one. At the start, the bottom-most LR EXA jumps to SYNC where it waits a bit. If I don't do that, it keeps trying to send early and I have to make all EXAs wait every cycle. Wasting a couple cycles at the start to make it sync up seems the better plan here.
After sending, both the LRLOOP and OLOOP take their EXAs back to their starting hosts and the whole process repeats. Those NOOPs in the LRLOOP are necessary to keep it in sync with the OLOOP.
Is there a way to speed up the OLOOP? Well, it'd be tight but what if that EXA goes back and forth, reading both ways?
code:
LINK 800
REPL RIGHT
REPL SYNC
LINK 1
REPL LRLOOP
REPL WRITER
LINK 1
JUMP LRLOOP
MARK WRITER
LINK 3
MARK WRITE
COPY -75 X
ADDI M X X
ADDI M X X
ADDI M X X
ADDI M X #NERV
JUMP WRITE
MARK SYNC
NOOP
MARK LRLOOP
TEST #NERV > -55
COPY T X
LINK -3
TEST #NERV > -55
ADDI X T X
MULI X 5 M
LINK 3
NOOP
NOOP
JUMP LRLOOP
MARK RIGHT
LINK -3
LINK -3
MARK OLOOP
TEST #NERV > -55
COPY T X
LINK 1
TEST #NERV > -55
ADDI X T X
LINK 1
TEST #NERV > -55
ADDI X T X
MULI X 5 M
NOOP
TEST #NERV > -55
COPY T X
LINK -1
TEST #NERV > -55
ADDI X T X
LINK -1
TEST #NERV > -55
ADDI X T X
MULI X 5 M
JUMP OLOOP
And... this code runs at 334/54/245. That is top percentile speed.
I think that is enough for this week. I wouldn't be surprised if an even lower speed is possible and I know a cycle count lower than 29 is possible, but that's for the thread.
Hopefully this is the last time you'll have to hack yourself like this.
The first vote, if it pleases you.
[deadlock] perfect
Nivas?? What are you doing there?
Anyway, I got a visitor.
It's Ghast. He looks different without his sunglasses.
Hey...
You hanging in there?
I just wanted to check up on you.
There's... no new issue of the zine yet.
It's going to be a while before I get it together.
Ghast pauses for a moment and takes a deep breath.
To be honest, I'm not sure if it'll happen.
It's getting harder for me to concentrate, and...
Well, let's not talk about that.
I just hope I was able to educate some people, you know?
Give them some power, some agency...
Otherwise we're all at the mercy of these big systems. You know my speech on this, but I can't help it man.
They're going to run right over our humanity. It's happening faster than we can handle, and soon...
Ghast's voice became quite agitated for that line. He sounds scared, or angry, or both...
Soon... it's all gonna be one big machine.
Hm. I've depressed myself again.
Listen, I'm glad to know you.
We had some good times, back in the day.
Alright. I'm gonna go before I get too sentimental.
See you around somewhere.
I'm out.
I can hear Ghast walking down the hall slowly.
Will this be the last time I see him?
There was an edge to his voice...
The dataphones were cute, but I still need more computing power.
We need to get me some significant hardware upgrades.
This is the vote for next time's intro.